﻿//
// USBC.cs
//
// Authors:
//    Claus Jørgensen <10229@iha.dk>
//    Jens Bloch Christensen <09584@iha.dk>
//    Jonas Daugaard Møller <08814@iha.dk>
//
using System;

namespace RSD.Robot
{
    /// <summary>
    /// Base class functionality, and USBC constants used by the <see cref="RobotController"/>.
    /// </summary>
    public abstract class USBC
    {
        /// <summary>
        /// Total axes available on the USBC-Controller.
        /// </summary>
        public const int TotalAxes = 8;

        /// <summary>
        /// Occurs when the initialization is completed.
        /// </summary>
        public event EventHandler<InitializationCompletedEventArgs> InitializationCompleted;

        /// <summary>
        /// Occurs when the homing status have changed.
        /// </summary>
        public event EventHandler<HomingStatusEventArgs> HomingStatusChanged;

        /// <summary>
        /// Occurs when digital input is received.
        /// </summary>
        public event EventHandler<IOEventArgs> DigitalInputReceived;

        /// <summary>
        /// Occurs when digital output is received.
        /// </summary>
        public event EventHandler<IOEventArgs> DigitalOutputReceived;

        /// <summary>
        /// Occurs when the joint status have changed.
        /// </summary>
        public event EventHandler<JointStatusEventArgs> JointStatusChanged;

        /// <summary>
        /// Occurs when the control status have changed.
        /// </summary>
        public event EventHandler<ControlStatusEventArgs> ControlStatusChanged;

        /// <summary>
        /// Occurs when a motion have started.
        /// </summary>
        public event EventHandler<MotionEventArgs> MotionStarted;

        /// <summary>
        /// Occurs when a motion have ended.
        /// </summary>
        public event EventHandler<MotionEventArgs> MotionEnded;

        /// <summary>
        /// Occurs when a unspecified action have started.
        /// </summary>
        public event EventHandler ActionStarted;

        /// <summary>
        /// Occurs when a unspecified action have completed.
        /// </summary>
        public event EventHandler ActionCompleted;

        /// <summary>
        /// Called when the initialization is completed.
        /// </summary>
        /// <param name="configuration">The configuration.</param>
        protected void OnInitializationCompleted(USBCConfiguration configuration)
        {
            if (InitializationCompleted != null)
            {
                InitializationCompleted(this,
                    new InitializationCompletedEventArgs(configuration));
            }
        }

        /// <summary>
        /// Called when an error occurs.
        /// </summary>
        /// <param name="error">The error.</param>
        protected void OnError(USBCError error)
        {
            //throw new USBCException(error.GetMessage());
            System.Diagnostics.Debug.WriteLine(error.GetMessage());
        }

        /// <summary>
        /// Called when digital input is received.
        /// </summary>
        /// <param name="status">The status.</param>
        protected void OnDigitalInputReceived(int status)
        {
            if (DigitalInputReceived != null)
            {
                DigitalInputReceived(this, new IOEventArgs(status));
            }
        }

        /// <summary>
        /// Called when digital output is received.
        /// </summary>
        /// <param name="status">The status.</param>
        protected void OnDigitalOutputReceived(int status)
        {
            if (DigitalOutputReceived != null)
            {
                DigitalOutputReceived(this, new IOEventArgs(status));
            }
        }

        /// <summary>
        /// Called when the homing status have changed.
        /// </summary>
        /// <param name="homingStatus">The homing status.</param>
        protected void OnHomingStatusChanged(char homingStatus)
        {
            if (HomingStatusChanged != null)
            {
                HomingStatusChanged(this,
                    new HomingStatusEventArgs((HomingStatus)homingStatus));
            }
        }

        /// <summary>
        /// Called when the joint status have changed.
        /// </summary>
        /// <param name="robotData">The robot data.</param>
        protected void OnJointStatusChanged(int[] robotData)
        {
            if (JointStatusChanged != null)
            {
                JointStatusChanged(this,
                    new JointStatusEventArgs(robotData));
            }
        }

        /// <summary>
        /// Called when a motion have started.
        /// </summary>
        /// <param name="axis">The movement axis.</param>
        protected void OnMotionStarted(byte axis)
        {
            if (MotionStarted != null)
            {
                MotionStarted(this,
                    new MotionEventArgs((Axis)axis));
            }
        }

        /// <summary>
        /// Called when a motion have ended.
        /// </summary>
        /// <param name="axis">The movement axis.</param>
        protected void OnMotionEnded(byte axis)
        {
            if (MotionEnded != null)
            {
                MotionEnded(this,
                    new MotionEventArgs((Axis)axis));
            }
        }

        /// <summary>
        /// Called when the control status have changed.
        /// </summary>
        /// <param name="axisStatus">The axis status.</param>
        protected void OnControlStatusChanged(uint axisStatus)
        {
            if (ControlStatusChanged != null)
            {
                ControlStatusChanged(this, new ControlStatusEventArgs(axisStatus));
            }
        }

        /// <summary>
        /// Called when a unspecified action have completed.
        /// </summary>
        protected void OnActionStarted()
        {
            if (ActionStarted != null)
            {
                ActionStarted(this, new EventArgs());
            }
        }

        /// <summary>
        /// Called when a unspecified action have completed.
        /// </summary>
        protected void OnActionCompleted()
        {            
            if (ActionCompleted != null)
            {
                ActionCompleted(this, new EventArgs());
            }
        }
    }
}
